import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.HashMap;

/**
 * 习题类 - 管理一组加减法算式的集合
 * 支持生成无重复的加减法习题，确保加减法比例控制
 * 
 * @author System Designer
 * @version 1.0
 */
public class ExerciseSet {
    // 成员变量（私有）
    private List<Expression> expressions; // 存储所有算式的列表
    private int totalCount;              // 总题目数量
    private Random random;               // 随机数生成器
    private static final double MIN_ADDITION_RATIO = 0.4; // 最小加法比例（40%）
    
    /**
     * 默认构造函数
     */
    public ExerciseSet() {
        this.expressions = new ArrayList<>();
        this.totalCount = 50; // 默认50道题
        this.random = new Random();
    }
    
    /**
     * 带参数构造函数
     * @param totalCount 总题目数量
     */
    public ExerciseSet(int totalCount) {
        this.expressions = new ArrayList<>();
        this.totalCount = totalCount;
        this.random = new Random();
    }
    
    /**
     * 带参数构造函数（指定随机种子）
     * @param totalCount 总题目数量
     * @param seed 随机种子
     */
    public ExerciseSet(int totalCount, long seed) {
        this.expressions = new ArrayList<>();
        this.totalCount = totalCount;
        this.random = new Random(seed);
    }
    
    /**
     * 生成指定数量的无重复习题
     */
    public void generateExercises() {
        expressions.clear(); // 清空现有算式
        
        Set<String> expressionSet = new HashSet<>(); // 用于去重
        
        // 计算需要的加法和减法数量
        int additionCount = (int) Math.ceil(totalCount * MIN_ADDITION_RATIO);
        int subtractionCount = totalCount - additionCount;
        
        int generatedAdditions = 0;
        int generatedSubtractions = 0;
        int totalGenerated = 0;
        
        while (totalGenerated < totalCount) {
            boolean isAddition;
            
            // 控制加法和减法的比例
            if (generatedAdditions < additionCount && generatedSubtractions < subtractionCount) {
                isAddition = random.nextBoolean();
            } else if (generatedAdditions < additionCount) {
                isAddition = true;
            } else {
                isAddition = false;
            }
            
            int num1, num2;
            char operator;
            
            if (isAddition) {
                // 生成有效的加法算式：确保结果不超过100
                num1 = random.nextInt(201) - 50; // -50到150
                int maxNum2 = 100 - num1;
                if (maxNum2 < -100) maxNum2 = -100;
                if (maxNum2 > 200) maxNum2 = 200;
                num2 = maxNum2 >= -100 ? random.nextInt(maxNum2 - (-100) + 1) + (-100) : -100;
                operator = '+';
            } else {
                // 生成有效的减法算式：确保结果非负
                num1 = random.nextInt(201) - 50; // -50到150
                int minNum2 = num1 - 100;
                if (minNum2 < -100) minNum2 = -100;
                int maxNum2 = num1;
                num2 = minNum2 <= maxNum2 ? random.nextInt(maxNum2 - minNum2 + 1) + minNum2 : minNum2;
                operator = '-';
            }
            
            // 创建算式
            Expression expression = new Expression(num1, operator, num2);
            String expressionKey = expression.formatExpression();
            
            // 检查是否已存在该算式
            if (!expressionSet.contains(expressionKey)) {
                expressionSet.add(expressionKey);
                expressions.add(expression);
                
                // 更新计数器
                if (isAddition) {
                    generatedAdditions++;
                } else {
                    generatedSubtractions++;
                }
                totalGenerated++;
            }
        }
    }
    
    /**
     * 添加算式到集合
     * @param expression 要添加的算式
     * @return true表示添加成功，false表示已存在或添加失败
     */
    public boolean addExpression(Expression expression) {
        if (expression == null) return false;
        
        String expressionKey = expression.formatExpression();
        for (Expression exp : expressions) {
            if (exp.formatExpression().equals(expressionKey)) {
                return false; // 已存在
            }
        }
        
        expressions.add(expression);
        return true;
    }
    
    /**
     * 检查是否已存在该算式
     * @param expression 要检查的算式
     * @return true表示已存在，false表示不存在
     */
    public boolean hasExpression(Expression expression) {
        if (expression == null) return false;
        
        String expressionKey = expression.formatExpression();
        for (Expression exp : expressions) {
            if (exp.formatExpression().equals(expressionKey)) {
                return true;
            }
        }
        return false;
    }
    
    /**
     * 计算统计数据
     * @return 包含统计信息的Map
     */
    public Map<String, Integer> calculateStatistics() {
        Map<String, Integer> stats = new HashMap<>();
        
        int additionCount = 0;
        int subtractionCount = 0;
        int validCount = 0;
        int invalidCount = 0;
        
        for (Expression exp : expressions) {
            if (exp.isAddition()) {
                additionCount++;
            } else if (exp.isSubtraction()) {
                subtractionCount++;
            }
            
            if (exp.isValid()) {
                validCount++;
            } else {
                invalidCount++;
            }
        }
        
        stats.put("total", expressions.size());
        stats.put("addition", additionCount);
        stats.put("subtraction", subtractionCount);
        stats.put("valid", validCount);
        stats.put("invalid", invalidCount);
        stats.put("additionRatio", expressions.size() > 0 ? (int)((double)additionCount / expressions.size() * 100) : 0);
        
        return stats;
    }
    
    /**
     * 显示所有算式（简单格式）
     */
    public void display() {
        System.out.println("===== 算式列表 =====");
        for (int i = 0; i < expressions.size(); i++) {
            System.out.println((i + 1) + ". " + expressions.get(i).toString());
        }
    }
    
    /**
     * 格式化显示算式（每行3个，带序号）
     */
    public void displayFormatted() {
        System.out.println("===== 格式化算式列表 =====");
        for (int i = 0; i < expressions.size(); i++) {
            Expression exp = expressions.get(i);
            System.out.printf("%2d. %s       ", (i + 1), exp.formatWithAnswer());
            
            // 每行显示3个算式
            if ((i + 1) % 3 == 0) {
                System.out.println();
            }
        }
        
        // 如果最后一行不满3个，换行
        if (expressions.size() % 3 != 0) {
            System.out.println();
        }
    }
    
    /**
     * 获取加法数量
     * @return 加法算式的数量
     */
    public int getAdditionCount() {
        int count = 0;
        for (Expression exp : expressions) {
            if (exp.isAddition()) {
                count++;
            }
        }
        return count;
    }
    
    /**
     * 获取减法数量
     * @return 减法算式的数量
     */
    public int getSubtractionCount() {
        int count = 0;
        for (Expression exp : expressions) {
            if (exp.isSubtraction()) {
                count++;
            }
        }
        return count;
    }
    
    /**
     * 获取总数量
     * @return 总算式数量
     */
    public int getTotalCount() {
        return expressions.size();
    }
    
    /**
     * 检查加法是否有效（和不超过100）
     * @param num1 第一个操作数
     * @param num2 第二个操作数
     * @return true表示有效，false表示无效
     */
    public boolean isValidAddition(int num1, int num2) {
        return (num1 + num2) <= 100;
    }
    
    /**
     * 检查减法是否有效（差不小于0）
     * @param num1 第一个操作数
     * @param num2 第二个操作数
     * @return true表示有效，false表示无效
     */
    public boolean isValidSubtraction(int num1, int num2) {
        return (num1 - num2) >= 0;
    }
    
    /**
     * 获取所有算式列表
     * @return 算式列表的副本
     */
    public List<Expression> getExpressions() {
        return new ArrayList<>(expressions);
    }
    
    /**
     * 设置随机数生成器
     * @param random 随机数生成器
     */
    public void setRandom(Random random) {
        this.random = random;
    }
    
    /**
     * 设置总数量
     * @param totalCount 总数量
     */
    public void setTotalCount(int totalCount) {
        this.totalCount = totalCount;
    }
    
    /**
     * 清空所有算式
     */
    public void clear() {
        expressions.clear();
    }
    
    /**
     * 重写toString方法
     * @return 字符串表示
     */
    @Override
    public String toString() {
        return String.format("ExerciseSet{totalCount=%d, expressions=%d}", 
                           totalCount, expressions.size());
    }
}